package cn.buk.qms.service;

import cn.buk.common.JsonResult;
import cn.buk.common.dto.eterm.PnrFlightDto;
import cn.buk.common.dto.eterm.PnrPassengerDto;
import cn.buk.common.flight.dto.FlightInfoDto;
import cn.buk.tms.dao.FlightCatchOrderDao;
import cn.buk.tms.sc.SearchFlightOrderCriteria;
import cn.buk.tms.entity.misc.*;
import cn.buk.tms.entity.order.flight.FlightCatchOrder;
import cn.buk.tms.entity.order.flight.FlightCatchOrderFlight;
import cn.buk.tms.entity.order.flight.FlightCatchOrderPassenger;
import cn.buk.tms.flight.request.FlightOrderRequestDto;
import cn.buk.common.util.DateUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Component;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author yfdai
 */
@Component
public class FlightCatchOrderServiceImpl extends BaseAbstractService implements FlightCatchOrderService {

    @Autowired
    private FlightCatchOrderDao dao;

    private JsonResult validateFlightOrder(FlightCatchOrder dto) {
        if (dto.getOldPnrNo().length() != 6
                && (dto.getFlights().isEmpty() || dto.getPassengers().isEmpty())) {
            return JsonResult.createJsonResult(-5, "航段信息和乘机人信息都必需有");
        }

        if (dto.getAuthOfficeNo().length() != 6 || !Pnr.testOfficeNoFormat(dto.getAuthOfficeNo())) {
            return JsonResult.createJsonResult(-1, "授权Office必须准确填写");
        }

        //TODO 此处需要改进 yfdai 2021-01-25
        for(FlightCatchOrderFlight flt: dto.getFlights()) {
            FlightInfo info = flt.getFlight();

            FlightInfoDto infoDto = new FlightInfoDto();
            BeanUtils.copyProperties(info, infoDto);

            try {
                infoDto.setDdate(DateUtil.convertToDate(info.getDdate(), "yyyy-MM-dd"));
            } catch (ParseException e) {
                e.printStackTrace();
            }

            JsonResult jsonResult = validateFlightInfo(infoDto, 0);
            if (jsonResult != null) {
              return jsonResult;
            }
        }

        // 乘机人联系电话不能重复
        Set<String> mobileSet = new HashSet<>();
        for(FlightCatchOrderPassenger psg: dto.getPassengers()) {
            mobileSet.add(psg.getMobile());

            JsonResult jsonResult = validateFlightCatchOrderPassenger(psg);
            if (jsonResult != null) {
                return jsonResult;
            }

        }

        if (mobileSet.size() < dto.getPassengers().size()) {
            return JsonResult.createJsonResult(-6, "联系人手机号不能重复");
        }


        return null;
    }

    private JsonResult validateFlightCatchOrderPassenger(FlightCatchOrderPassenger psg) {
        if (psg.getName().length() < 2) {
            return JsonResult.createJsonResult(-5, "姓名(" + psg.getName() + ")" + "不符合格式要求");
        }
        if (psg.getIdNo().length() < 2 && psg.getPsgType() != 2) {
            return JsonResult.createJsonResult(-5, "证件号(" + psg.getIdNo() + ")" + "不符合格式要求");
        }

        if (psg.getMobile().length() != 11) {
            return JsonResult.createJsonResult(-5, "手机(" + psg.getMobile() + ")" + "不符合格式要求");
        }

        return null;
    }

    /**
     * 创建追位订单
     *
     * @param enterpriseId 企业id
     * @param username     用户名
     * @param dto          FlightOrderDto
     */
    @Override
    public JsonResult createOrder(final int enterpriseId, final String username, final String remoteAddr, FlightOrderRequestDto dto) {
        //校验追位产品是否已过期
        if (!"127.0.0.1".equalsIgnoreCase(remoteAddr)) {
            JsonResult jsonResult = enterpriseService.checkProductExpireDate(enterpriseId, Product.ETERM_AUTO_SS);
            if (!JsonResult.STATUS_OK.equalsIgnoreCase(jsonResult.getStatus())) {
                return jsonResult;
            }
        }

        // 乘机人证件、手机号、姓名都需要
        // 手机号不能相同

        // 将DTO中的内容转化到FlightOrder中
        FlightCatchOrder info = new FlightCatchOrder();
        BeanUtils.copyProperties(dto, info);

        info.setEnterpriseId(enterpriseId);
        info.setOldPnrNo(dto.getPnrNo());

        info.setFlights(null);
        info.setPassengers(null);

        // 航段信息
        int segOrd = 0;
        Set<FlightCatchOrderFlight> flts = info.getFlights();
        for (PnrFlightDto flt : dto.getFlights()) {
            segOrd++;

            FlightCatchOrderFlight detail = new FlightCatchOrderFlight();

            BeanUtils.copyProperties(flt.getFlight(), detail.getFlight());

            detail.setEnterpriseId(info.getEnterpriseId());
            detail.getFlight().setDdate(flt.getFlight().getDdateFormatted());
            detail.setSegOrder(segOrd);
            detail.setOrder(info);

            flts.add(detail);
        }

        // 乘机人信息
        Set<FlightCatchOrderPassenger> psgs = info.getPassengers();
        for (PnrPassengerDto psg : dto.getPassengers()) {
            if (!psg.isSelected() || psg.getPsgName().length() < 2) {
              continue;
            }

            FlightCatchOrderPassenger detail = new FlightCatchOrderPassenger();

            BeanUtils.copyProperties(psg, detail);

            detail.setEnterpriseId(info.getEnterpriseId());
            detail.setOrder(info);
            detail.setName(psg.getPsgName());
            detail.setIdNo(psg.getIdNo());

            psgs.add(detail);
        }

        //内容验证
        JsonResult validateResult =  validateFlightOrder(info);
        if (validateResult != null) {
          return validateResult;
        }

        int retCode = dao.createOrder(info, username);
        return JsonResult.createJsonResult(retCode);
    }

    private void clean(FlightCatchOrder order) {
        if (order == null) {
          return;
        }

        for (FlightCatchOrderFlight flt : order.getFlights()) {
            flt.setOrder(null);
        }

        for (FlightCatchOrderPassenger psg : order.getPassengers()) {
            psg.setOrder(null);
        }

    }

    @Override
    public List<FlightCatchOrder> searchFlightOrders(int enterpriseId, int userId, String username, SearchFlightOrderCriteria sc) {

        sc.setBeginDate(DateUtil.addDays(DateUtil.getCurDate(), -365));

        List<FlightCatchOrder> flightOrders = dao.searchOrder(enterpriseId, username, sc);

        if (flightOrders == null) {
          flightOrders = new ArrayList<>();
        }

        for (FlightCatchOrder order : flightOrders) {
            clean(order);
        }

        return flightOrders;
    }

    @Override
    public FlightCatchOrder getFlightOrderDetail(int enterpriseId, int id) {
        FlightCatchOrder flightOrder = dao.getOrder(id);
        if (flightOrder != null && flightOrder.getEnterpriseId() != enterpriseId) {
            return null;
        }

        clean(flightOrder);

        return flightOrder;
    }

    /**
     * 修改机票订单中的乘机人信息
     * @param enterpriseId 企业标示
     * @param orderId 订单ID
     * @param id id
     * @param name name
     * @param idNo idNo
     * @param ffpNo ffpNo
     */
    @Override
    public JsonResult updateFlightOrderPassenger(int enterpriseId, int orderId, int id, String name, String idNo, String ffpNo, String mobile) {
        int retCode = dao.updatePassenger(enterpriseId, orderId, id, name, idNo, ffpNo, mobile);
        return JsonResult.createJsonResult(retCode);
    }

    /**
     * 修改订单备注
     */
    @Override
    public JsonResult updateFlightOrderRemark(int enterpriseId, String username, int orderId, String remark) {
        int retCode = dao.updateRemark(enterpriseId, username, orderId, remark);
        return JsonResult.createJsonResult(retCode);
    }

    /**
     * 修改订单的pnr
     */
    @Override
    public JsonResult updateFlightOrderPnr(int enterpriseId, String username, int orderId, String pnrNo) {
        pnrNo = pnrNo.trim().toUpperCase();
        if (pnrNo.length() < 5 || pnrNo.length() > 6) {
            return JsonResult.createJsonResult(-1, "编码长度不符合要求，应该介于5-6间");
        }

        int retCode = dao.updatePnr(enterpriseId, username, orderId, pnrNo);
        return JsonResult.createJsonResult(retCode);
    }

    /**
     * 取消机票订单
     * @param enterpriseId 当前用户的enterpriseId
     * @param username 当前用户的username
     * @param orderId 订单id
     * @param reasonCode 取消理由的代码
     * @param reasonDesc 取消理由
     */
    @Override
    public JsonResult cancelFlightOrder(int enterpriseId, String username, int orderId, int reasonCode, String reasonDesc) {
        FlightCatchOrder flightOrder = dao.getOrder(orderId);

        if (flightOrder == null || flightOrder.getEnterpriseId() != enterpriseId) {
            return JsonResult.createJsonResult(-1, "没有此订单");
        }

        if (flightOrder.getStatus() == FlightCatchOrder.STATUS_DONE
                || flightOrder.getStatus() == FlightCatchOrder.STATUS_CANCELED) {
            return JsonResult.createJsonResult(-2, "此订单无法取消");
        }

        int retCode = 0;

        if (flightOrder.getStatus() == FlightCatchOrder.STATUS_WAITING
                || flightOrder.getStatus() == FlightCatchOrder.STATUS_PROCESSING) {

            retCode = dao.cancelFlightOrder(enterpriseId, username, orderId, reasonCode, reasonDesc);

            return JsonResult.createJsonResult(retCode);

        }

        return null;
    }

    /**
     * 重新监控追位订单
     */
    @Override
    @Secured({RoleInfo.ROLE_ADMIN})
    public JsonResult monitorFlightCatchOrder(int enterpriseId, String username, int orderId) {
        int retCode = dao.monitorFlightCatchOrder(enterpriseId, username, orderId);
        return JsonResult.createJsonResult(retCode);
    }

    @Override
    @Secured({RoleInfo.ROLE_ADMIN})
    public JsonResult deleteCatchOrder(int enterpriseId, int orderId) {
        int retCode = dao.deleteCatchOrder(enterpriseId, orderId);
        return JsonResult.createJsonResult(retCode);
    }


    @Override
    public List<OperationLog> searchFlightOrderHistory(int enterpriseId, int orderId) {
        return dao.searchHistory(enterpriseId, orderId);
    }

}
